<template>
  <div class="w-full overflow-hidden">
    <a-space class="w-full overflow-auto" direction="vertical" size="small">
      <a-card v-if="isSearch" class="main w-full" :bordered="false" :loading="loading">
        <SearchModule
          v-bind="{ searchList, searchParams }"
          @reset-fields="resetFields"
          @search-fun="(params) => emit('loadData', { ...params, current: 1 })"
        >
          <template #searchQuery>
            <slot name="searchQuery"></slot>
          </template>
          <template #searchBtn>
            <slot name="searchBtn"></slot>
          </template>
        </SearchModule>
      </a-card>
      <a-card class="w-full" :bordered="false" :loading="loading">
        <a-space class="w-full" direction="vertical" size="middle">
          <slot name="tableTop"></slot>
          <a-table
            :data-source="list"
            v-bind="props.columnProps"
            :columns="privateColumns"
            :pagination="pagination"
            @change="onChangePage"
          >
            <template #bodyCell="{ text, record, index, column }">
              <slot name="operation" :text="text" :record="record" :index="index" :column="column">
                <template v-if="column.dataIndex === 'operation'">
                  <template v-for="(item, aIndex) in column.actions" :key="aIndex">
                    <template
                      v-if="
                        (item.vIf && typeof item.vIf === 'boolean') ||
                        (item.vIf && item.vIf(record))
                      "
                    >
                      <a v-if="!item?.text" href="javascript:" @click="item.onClick(record)">
                        {{ item.title || item.statusText(record) }}
                      </a>
                      <span v-else class="text-hex-999">{{ item.title }}</span>
                      <a-divider
                        v-if="!item?.text && aIndex + 1 < vIfActionsLine(column.actions, record)"
                        type="vertical"
                      />
                    </template>
                  </template>
                </template>
              </slot>
            </template>
          </a-table>
          <slot name="tableBottom"></slot>
        </a-space>
      </a-card>
    </a-space>
  </div>
</template>

<script setup>
  import SearchModule from './components/searchModule.vue';

  const props = defineProps({
    queryParamsSlots: {
      type: [Object],
      default: () => {
        return {};
      },
    },
    pageParams: {
      type: [Object, Boolean],
    },
    list: {
      type: Array,
      default: () => {
        return [];
      },
    },
    columns: {
      type: Array,
      default: () => {
        return [];
      },
    },
    loading: {
      type: Boolean,
      default: () => {
        return false;
      },
    },
    columnProps: {
      type: Object,
      default: () => {
        return {};
      },
    },
  });
  const { queryParamsSlots, pageParams, list, loading, columns } = toRefs(props);
  // 私有columns
  const privateColumns = ref(columns || {});
  const isSearch = computed(() => {
    return (
      privateColumns.value?.filter((item) => item.search === true)?.length ||
      Object.keys(queryParamsSlots.value).length
    );
  });
  const emit = defineEmits(['loadData', 'resetData']);
  const sortParams = ref({ sortColumn: null, sortAsc: null });

  const vIfActionsLine = (item, record) => {
    return (
      item?.filter(
        (item) => (item.vIf && typeof item.vIf === 'boolean') || (item.vIf && item.vIf(record)),
      )?.length || 0
    );
  };

  const searchList = privateColumns.value?.filter((item) => item.search === true);
  const searchParams = ref(
    searchList.reduce((query, item) => {
      query[item.alias ?? item.dataIndex] = null;
      return query;
    }, {}),
  );

  watchEffect(() => {
    searchParams.value = { ...searchParams.value, ...queryParamsSlots.value };
  });

  const resetFields = () => {
    searchParams.value = searchList.reduce((query, item) => {
      query[item.alias ?? item.dataIndex] = null;
      return query;
    }, {});
    emit('resetData', { current: 1, ...searchParams.value });
  };

  const onChangePage = (page, filters, sorter, extra) => {
    setSortParams(sorter);
    // 当触发不是分页也不是排序的时候，不触发请求
    if (['paginate', 'sort'].includes(extra.action)) {
      emit('loadData', {
        current: page.current,
        size: page.pageSize,
        ...searchParams.value,
        ...sortParams.value,
      });
      setSortOrder();
    }
  };

  const setSortParams = (sorter) => {
    sortParams.value = sorter.order
      ? {
          sortColumn: sorter.column.sorterFiled || sorter.column.alias || sorter.column.dataIndex,
          sortAsc: sorter.order === 'ascend',
        }
      : { sortColumn: null, sortAsc: null };
  };

  const setSortOrder = () => {
    privateColumns.value.forEach((item) => {
      if (item.sorter) {
        item.sortOrder =
          (item.sorterFiled || item.dataIndex) === sortParams.value.sortColumn
            ? sortParams.value.sortAsc
              ? 'ascend'
              : 'descend'
            : false;
      }
    });
  };

  const pagination = computed(() => {
    return pageParams?.value
      ? {
          current: pageParams.value.current,
          pageSize: pageParams.value.size,
          total: pageParams.value?.total,
        }
      : false;
  });
  defineExpose({ resetFields });
</script>

<style scoped lang="less">
  @import '@/styles/animation.less';
  :deep(.ant-table-content) {
    overflow: auto;
  }
  :deep(.ant-btn) {
    .throttle_animation();
  }
</style>
